package com.zmn.oms.dubbo.impl.zmn.master.order;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.oms.business.interfaces.es.OrderWorkEsBService;
import com.zmn.oms.common.constant.OrderConsts;
import com.zmn.oms.common.dio.normal.master.MasterWorkCountDIO;
import com.zmn.oms.common.dro.normal.master.MasterCompletedWorkCount;
import com.zmn.oms.common.dro.normal.master.MasterWorkCountDRO;
import com.zmn.oms.dubbo.interfaces.zmn.master.order.MasterWorkStatRemoteService;
import com.zmn.oms.dubbo.utils.DubboConsts;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.dubbo.config.annotation.Service;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.terms.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;

import java.util.*;

/**
 * 类描述：工程师统计
 *
 * @author heciqi
 * @date 2021/8/27 10:38
 */
@Slf4j
@Service(loadbalance = "roundrobin", timeout = 5000, retries = 2, version = DubboConsts.INTERFACE_VERSION, validation = "false")
public class MasterWorkStatRemoteServiceImpl implements MasterWorkStatRemoteService {

    @Autowired
    private OrderWorkEsBService orderWorkEsBService;

    /**
     * 工程师完成工单数
     *
     * @param masterIds
     * @param startTime
     * @param endTime
     * @return
     */
    @Override
    public ResponseDTO<List<MasterCompletedWorkCount>> listMasterCompletedWorkCount(List<Integer> masterIds, Date startTime, Date endTime) {
        log.info("工程师完成单统计，入参：masterIds {}，startTime {}，endTime {}", masterIds, startTime, endTime);

        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery()
                .filter(QueryBuilders.termsQuery("masterId", masterIds));
        RangeQueryBuilder completeTimeRange = QueryBuilders.rangeQuery("completeTime");
        if (Objects.nonNull(startTime)) {
            completeTimeRange.gte(DateUtil.toString(startTime));
        }
        if (Objects.nonNull(endTime)) {
            completeTimeRange.lte(DateUtil.toString(endTime));
        }
        queryBuilder.filter(completeTimeRange);

        NativeSearchQuery searchQuery = new NativeSearchQuery(queryBuilder);
        searchQuery.setPageable(PageRequest.of(0, 1));
        // 工程师分组
        String groupFiled = "masterId";
        TermsAggregationBuilder termsAggregationBuilder = AggregationBuilders.terms(groupFiled)
                .field(groupFiled);
        searchQuery.addAggregation(termsAggregationBuilder);
        termsAggregationBuilder.size(500);
        log.info("工程师完成单统计es===>{}", queryBuilder.toString());
        Aggregations query1 = orderWorkEsBService.getAggregationsByQuery(searchQuery);
        ParsedTerms parsedStringTerms = query1.get(groupFiled);
        List<? extends Terms.Bucket> buckets = parsedStringTerms.getBuckets();
        if (CollectionUtils.isEmpty(buckets)) {
            return ResponseDTO.success(Collections.emptyList());
        }

        List<MasterCompletedWorkCount> list = Lists.newArrayList();
        buckets.forEach(bucket -> {
            // 网格
            MasterCompletedWorkCount obj = new MasterCompletedWorkCount();
            obj.setMasterId(Integer.valueOf(bucket.getKeyAsString()));
            obj.setWorkCount(bucket.getDocCount());
            list.add(obj);
        });
        log.info("工程师完成单统计返回===>{}", list);
        return ResponseDTO.success(list);
    }

    /**
     * 工程师工单数统计
     *
     * @param masterWorkCountDIO
     * @return
     */
    @Override
    public ResponseDTO<List<MasterWorkCountDRO>> listMasterWorkCount(MasterWorkCountDIO masterWorkCountDIO) {
        log.info("工程师工单统计，入参：{}", JSON.toJSONString(masterWorkCountDIO));

        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery()
                .filter(QueryBuilders.termsQuery("masterId", masterWorkCountDIO.getMasterIdList()));

        RangeQueryBuilder timeRange = QueryBuilders.rangeQuery(masterWorkCountDIO.getTimeType().getCode());
        if (Objects.nonNull(masterWorkCountDIO.getStartTime())) {
            timeRange.gte(DateUtil.toString(masterWorkCountDIO.getStartTime()));
        }
        if (Objects.nonNull(masterWorkCountDIO.getEndTime())) {
            timeRange.lte(DateUtil.toString(masterWorkCountDIO.getEndTime()));
        }
        queryBuilder.filter(timeRange);

        if (CollectionUtils.isNotEmpty(masterWorkCountDIO.getOrderTypeList())) {
            queryBuilder.filter(QueryBuilders.termsQuery("type", masterWorkCountDIO.getOrderTypeList()));
        } else {
            queryBuilder.filter(QueryBuilders.termsQuery("type", Lists.newArrayList(OrderConsts.ORDER_TYPE_NEW, OrderConsts.ORDER_TYPE_REWORK)));
        }

        // queryBuilder.filter(QueryBuilders.termQuery("isTest", false)).filter(QueryBuilders.termQuery("isDuplicate", false));

        NativeSearchQuery searchQuery = new NativeSearchQuery(queryBuilder);
        searchQuery.setPageable(PageRequest.of(0, 1));
        // 工程师分组
        String groupFiled = "masterId";
        TermsAggregationBuilder termsAggregationBuilder = AggregationBuilders.terms(groupFiled)
                .field(groupFiled);
        searchQuery.addAggregation(termsAggregationBuilder);
        termsAggregationBuilder.size(500);
        log.info("工程师工单统计es===>{}", queryBuilder.toString());
        Aggregations query1 = orderWorkEsBService.getAggregationsByQuery(searchQuery);
        ParsedTerms terms = query1.get(groupFiled);
        List<? extends Terms.Bucket> buckets = terms.getBuckets();
        if (CollectionUtils.isEmpty(buckets)) {
            return ResponseDTO.success(Collections.emptyList());
        }

        List<MasterWorkCountDRO> list = Lists.newArrayList();
        buckets.forEach(bucket -> {
            MasterWorkCountDRO obj = new MasterWorkCountDRO();
            obj.setMasterId(Integer.valueOf(bucket.getKeyAsString()));
            obj.setWorkCount(bucket.getDocCount());
            list.add(obj);
        });
        log.info("工程师工单统计返回===>{}", list);
        return ResponseDTO.success(list);
    }
}
